package hhf.common.acid.service {
	import flash.utils.Proxy;
	import flash.utils.flash_proxy;
	
	import hhf.common.acid.event.ServiceEvent;
	import hhf.common.acid.method.method;
	
	import mx.controls.Alert;
	import mx.core.Application;
	import mx.core.mx_internal;
	import mx.resources.IResourceManager;
	import mx.resources.ResourceManager;
	import mx.rpc.AbstractOperation;
	import mx.rpc.AbstractService;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;
	
	use namespace flash_proxy;
	use namespace mx_internal;

	[Bindable(event="operationsChange")]
	public dynamic class Service extends Proxy {

	    private var resourceManager:IResourceManager = ResourceManager.getInstance();
	    mx_internal var _operations:Object;
		mx_internal var bean:AbstractService = null; 
	    public var methods:Array;
	    public var showBusyCursor:Boolean = false;
	    public var destination:String;
	    public var endPoint:String;

		public function Service() {
	        _operations = {};
	        methods = new Array();
		}

		private var _inject:String;
		public function set inject(inject:String):void {
			if(inject!=null) {
				this._inject = inject;
				var evt:ServiceEvent = new ServiceEvent(ServiceEvent.ASK_INJECTION, inject, this);
				Application.application.dispatchEvent(evt)  
			}
		}

		public function getOperation(name:String):AbstractOperation {
 		    var op:AbstractOperation = _operations[name];
 		    var showBusyCursor:Boolean = this.showBusyCursor; 
			if(op == null) {
				if(this.bean==null&&destination!=null) {
			    	this.bean = new RemoteObject(destination);
			    	if(endPoint!=null) (this.bean as RemoteObject).endPoint = endPoint;
			    }
			    if (this.bean!=null) {
			        methods.forEach(function(element:*, index:int, arr:Array):void {
			        	if(element is method) {
			        		var met:method = element as method;
				        	if(met.name == name) {
				        		if(!met.shared&&this is RemoteObject) {
							    	var ro:RemoteObject = new RemoteObject((this as RemoteObject).destination);
							    	ro.showBusyCursor = showBusyCursor;
							    	ro.endpoint = (this as RemoteObject).endpoint;
							    	op = ro.getOperation(name);
						        	op.asyncRequest = ro.asyncRequest;
				        		} else {
							    	this.showBusyCursor = showBusyCursor;
							        op = this.getOperation(name);
						        	op.asyncRequest = this.asyncRequest;
						        }
				        		if(met.resultHandler!=null) op.addEventListener(ResultEvent.RESULT, met.resultHandler, false);
				        		if(met.faultHandler!=null) op.addEventListener(FaultEvent.FAULT, met.faultHandler, false);
				        	}
			        	}
			        }, this.bean);
			        _operations[name] = op;
			    }
			}
		    return op;
		}
			
 	    override flash_proxy function getProperty(name:*):* {
	        return getOperation(name);
	    }

 	    override flash_proxy function callProperty(name:*, ... args:Array):* {
 	    	var op:AbstractOperation = getOperation(name); 
 	    	if(op!=null) return op.send.apply(null, args);
 	    	return null;
	    }
	}
}